#pragma once // Prevent the header file from being included multiple times

#include <iostream> // Include the input-output library for subsequent I/O operations
#include <opencv2/core/mat.hpp>
#include <opencv2/opencv.hpp>

#define C_SHARP_MAX_OBJECTS 1000 // Define the maximum number of objects that can be detected

// The bbox_t structure is used to represent bounding box information
struct bbox_t {
    int id = -1; // Unique identifier for the bounding box, default is -1
    float prob = 0.f; // Confidence, the probability that the bounding box contains an object
    unsigned int x{}, y{}, w{}, h{}; // (x,y) are the top-left coordinates of the bounding box, (w, h) are the width and height
};

struct image_t {
    cv::Mat rgbf; // Float type image data (CV_32F)
    cv::Mat rgb8; // 8-bit image data (CV_8U)
    cv::Mat rgb16; // 16-bit image data (CV_16U)

    int h = 0; // Image height
    int w = 0; // Image width
    int c = 0; // Number of channels, common values are 3 (RGB images)
};

// The st_dlm_data structure contains the images and parameters needed for object detection
struct st_dlm_data
{
    image_t img; // Store the image to be processed

    float prob_threshold = 0.3f; // The probability threshold for filtering low-confidence bounding boxes
    float nms_threshold = 0.5f; // Non-maximum suppression threshold for eliminating overlapping bounding boxes

    bbox_t result_boxs[C_SHARP_MAX_OBJECTS]; // Store the bounding boxes in the detection results
    int result_box_num = 0; // The number of bounding boxes in the detection results, initially 0
};

// The bbox_t_container is used to store multiple bounding boxes, with the maximum number limited by C_SHARP_MAX_OBJECTS
struct bbox_t_container {
    bbox_t candidates[C_SHARP_MAX_OBJECTS]; // Array to store bounding box candidates
};

//==========================================================================================
enum PRECISION_MODE // Precision mode enumeration
{
    PRECISION_FP32, // 32-bit floating point (single precision)
    PRECISION_FP16, // 16-bit floating point (half precision)
    PRECISION_INT8, // 8-bit integer
};

// The st_trans_model_input structure contains model input information
struct st_trans_model_input 
{
    std::string cfg_path; // Path to the configuration file
    std::string model_path; // Path to the model file

    PRECISION_MODE precision = PRECISION_FP16; // Set the default precision to FP16
    std::string gpu_model = "NVIDIA GeForce RTX 3060"; // The model of the GPU used

    std::string trans_path; // Path to the converted file
};

// Define a new structure to store length information
struct st_encrypt_header {
    size_t struct_size;   // Size of the st_encrypt_info_ovino structure
    size_t xml_size;      // Size of the XML file
    size_t bin_size;      // Size of the BIN file
};

// Maximum number of anchors and strides defined
static constexpr int MAX_NUM_ANCHORS = 4;
static constexpr int MAX_STRIDES = 4;

// The st_encrypt_info_ovino structure is used to store information related to the encrypted model
struct st_encrypt_info_ovino {
    char gpu_model[100] = {0}; // Store the GPU model, character array initialized to 0

    int batch_size = 0; // Batch size
    int class_num = 0; // Number of classes
    int input_channel = 0; // Number of input channels
    int image_width = 0; // Width of the input image
    int image_height = 0; // Height of the input image

    int num_anchors_size = 0; // Actual number of anchors
    int num_anchors[MAX_NUM_ANCHORS] = {0}; // Store the number of each type of anchor

    int stride_num = 0; // Number of strides
    int strides[MAX_STRIDES] = {0}; // Store different strides

    bool dynamic = false; // Choose whether to dynamically allocate
    int engine_size = 0; // Engine size

    float obj_threshold{};            // Object detection threshold
    float nms_threshold{};            // Non-maximum suppression threshold
};